﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace Expand.Collections.Generic
{
    /// <summary>
    /// FIXME: Not working
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class ReverseLinkedList<T> : LinkedList<T>, IEnumerable<T>, IEnumerable
    {
        public new IEnumerator<T> GetEnumerator()
        {
            return new ReverseLinkedListEnumerator(this);
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return new ReverseLinkedListEnumerator(this);
        }

        public struct ReverseLinkedListEnumerator : IEnumerator<T>, IDisposable, IEnumerator
        {
            private LinkedListNode<T> _Current;

            private LinkedList<T> _Owner;
            public LinkedList<T> Owner { get { return _Owner; } }

            public ReverseLinkedListEnumerator(LinkedList<T> linkedList)
            {
                _Current = null;
                _Owner = linkedList;
            }

            public T Current
            {
                get
                {
                    if (_Current == null) throw new InvalidOperationException("Current value never moved to next one");
                    else return _Current.Value;
                }
            }

            public void Dispose()
            {
                _Current = null;
                _Owner = null;
            }

            object IEnumerator.Current
            {
                get
                {
                    if (_Current == null) throw new InvalidOperationException("Current value never moved to next one");
                    else return _Current.Value;
                }
            }

            public bool MoveNext()
            {
                if (_Current == null && Owner.Last == null) return false;
                if (_Current == null) _Current = Owner.Last;
                else if (_Current == Owner.First) return false;
                else _Current = _Current.Previous;
                return true;
            }

            public void Reset()
            {
                _Current = null;
            }
        }
    }
}
